/*
dictionariesmanager.cpp
(c) 2010 Yury Hamenkov
This file is part of qWordCards.

qWordCards is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

qWordCards is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with qWordCards. If not, see <http://www.gnu.org/licenses/>.
*/

#include "dictionariesmanager.h"
#include "dictionaryloadthread.h"
#include "word.h"
#include <QIcon>
//#include "dictionary.h"
#ifdef DEBUG
	#include <QDebug>
#endif

using namespace qWordCards;

DictionariesManager::DictionariesManager(QObject *parent) :
    QObject(parent)
{
	// Dicts loading thread
	_thread = new DictionaryLoadThread(this);
	QObject::connect(_thread, SIGNAL(finished()), this, SLOT(sl_DictionaryLoadingCompleted()));
	setObjectName("DictionariesManager");
	_menu = new QMenu();
	_menu->setTitle(tr("Select dictionaries"));
}

DictionariesManager::~DictionariesManager() {
	delete _thread;
	delete _menu;
}

void DictionariesManager::ReloadDictionaries() {
	QDir dir("./dicts");
	// Scan './dicts' dir for dictionary files
	ScanDir(dir);
	_thread->SetList(_dicts);
	_thread->start();
}

int DictionariesManager::DictionariesCount() const {
	return _dicts.count();
}

int DictionariesManager::WordsCount() const {
	int count = 0;
	foreach (Dictionary* d, _dicts) {
		count += d->GetWordsCount();
	}
	return count;
}

void DictionariesManager::ScanDir(QDir dir) {
	// Delete non-existent dictionaries
	foreach (Dictionary* d, _dicts) {
		if (!QFileInfo(d->GetFileName().append(".dict.dz")).exists() || !QFileInfo(d->GetFileName().append(".idx")).exists()) {
			_dicts.removeOne(d);
#ifdef DEBUG
			qDebug() << QString("File '%1' doesn't exists. Deleting dictionary '%2'.").arg(d->GetFileName()).arg(d->GetName());
#endif
			//emit sg_ActionHolderDeleting(d->Action());
			delete d;
		}
	}
	

	QList<QFileInfo> files = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files);

	foreach(QFileInfo f, files) {
		if (f.isDir()) {
			ScanDir(QDir(f.absoluteFilePath()));
		} else if (f.isFile()) {
			if (f.completeSuffix().toLower() == "dict.dz") {
				if (!QFileInfo(f.absolutePath().append("/").append(f.baseName()).append(".idx")).exists()) {continue;} // .idx file is required
				if (f.size() == 0) {continue;}
				bool exists = false;
				foreach(Dictionary* d, _dicts) { // check if file was loaded earlier
					if (d->GetFileName() == f.absolutePath().append("/").append(f.baseName())) {
						exists = true;
						break;
					}
				}
				if (!exists) {
					Dictionary* d = new Dictionary(f.absolutePath().append("/").append(f.baseName()), 0);
					_dicts << d;
				}
			}
		}
	}
}

QMap <QString, bool> DictionariesManager::GetDictionariesActivity() const {
	QMap <QString, bool> activity;
	foreach (Dictionary* d, _dicts) {
		activity.insert(d->GetFileName(), d->IsUsed());
	}
	return activity;
}

void DictionariesManager::SetFavourite(QString s, bool t) {
	foreach (Dictionary* d, _dicts) {
		if (d->IsLoaded()) {
			d->SetFavourite(s, t);
		}
	}
}

void DictionariesManager::SetKnown(QString s, bool t) {
	foreach (Dictionary* d, _dicts) {
		if (d->IsLoaded()) {
			d->SetKnown(s, t);
		}
	}
}

void DictionariesManager::SetSuspended(QString s, bool t) {
	foreach (Dictionary* d, _dicts) {
		if (d->IsLoaded()) {
			d->SetSuspended(s, t);
		}
	}
}

int DictionariesManager::FavouriteWordsCount() const {
	int c = 0;
	foreach (Dictionary* d, _dicts) {
		if (d->IsLoaded()) {
			c+= d->FavouriteWordsCount();
		}
	}
	return c;
}

int DictionariesManager::KnownWordsCount() const {
	int c = 0;
	foreach (Dictionary* d, _dicts) {
		if (d->IsLoaded()) {
			c+= d->KnownWordsCount();
		}
	}
	return c;
}

int DictionariesManager::OrdinalWordsCount() const {
	int c = 0;
	foreach (Dictionary* d, _dicts) {
		if (d->IsLoaded()) {
			c+= d->OrdinalWordsCount();
		}
	}
	return c;
}

Word DictionariesManager::GetWord(WordType type) const {
	QList<Dictionary*> list;
	foreach(Dictionary*d, _dicts) {
		if (d->IsLoaded() && d->IsUsed()) {
			list << d;
		}
	}
	if (type == qWordCards::Favourite) {
		foreach (Dictionary*d, list) {
			if (d->FavouriteWordsCount() == 0) {
				list.removeOne(d);
			}
		}
	} else if (type == qWordCards::Ordinal) {
		foreach (Dictionary*d, list) {
			if (d->OrdinalWordsCount() == 0) {
				list.removeOne(d);
			}
		}
	}
	// list can be empty !!!!!!!!!!!!!!!!!!!
	int dictNumber = qrand() % list.count();
	return list[dictNumber]->GetWord(type);
}

Dictionary* DictionariesManager::operator[](int index) {
	return _dicts[index];
}

Dictionary* DictionariesManager::operator[](QString name) {
	foreach (Dictionary* d, _dicts) {
		if (d->GetName() == name) {
			return d;
		}
	}
	return NULL;
}

QMenu* DictionariesManager::GetMenu() const {
	return _menu;
}

void DictionariesManager::sl_DictionaryLoadingCompleted() {
	// Fill dict select menu
	QIcon ICNBook(QPixmap(":/icons/book.png"));
	QIcon ICNBookQuestion(QPixmap(":/icons/book-question.png"));
	
	QAction* act;
	_menu->clear();
	act = _menu->addAction(tr("All"), this, SLOT(sl_SelectDictPressed()));
	act->setCheckable(true);
	foreach(Dictionary* d, _dicts) {
		act = _menu->addAction(d->GetName(), this, SLOT(sl_SelectDictPressed()));
		if (d->IsLoaded()) {
			act->setIcon(ICNBook);
			act->setCheckable(true);
		} else {
			act->setIcon(ICNBookQuestion);
			act->setCheckable(false);
		}
		
		act->setToolTip(d->GetFileName());
		if (d->IsUsed()) {
			act->setChecked(true);
		} else {
			act->setChecked(false);
		}
	}
	
	emit sg_LoadingComplete();
}

void DictionariesManager::sl_SelectDictPressed() {
	QAction* act = dynamic_cast<QAction*>(QObject::sender());

	if (act->text() == tr("All")) { // потенциальная ошибка, может быть словарь с именем All
		foreach(QAction* a, _menu->actions()) {
			if (a == act) {continue;}
			a->setChecked(act->isChecked());
		}
	} else {
		foreach(Dictionary* d, _dicts) {
			if (d->GetFileName() == act->toolTip()) {
				d->SetUsed(act->isChecked());
				break;
			}
		}
	}
}
